package org.x4444.myws;

import java.io.IOException;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.websocket.WebSocket;
import org.eclipse.jetty.websocket.WebSocketServlet;

/**
 * Servlet implementation class MyWs
 */
public class MyWs extends WebSocketServlet {
    private static final long serialVersionUID = 1L;

    private final Set<ChatWebSocket> members = new CopyOnWriteArraySet<ChatWebSocket>();

    /**
     * @see HttpServlet#HttpServlet()
     */
    public MyWs() {
        super();
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        getServletContext().getNamedDispatcher("default").forward(request, response);
    }

    @Override
    public WebSocket doWebSocketConnect(HttpServletRequest arg0, String arg1) {
        return new ChatWebSocket();
    }

    class ChatWebSocket implements WebSocket.OnTextMessage {

        Connection conn;

        @Override
        public void onClose(int arg0, String arg1) {
            members.remove(this);
            System.out.println("onClose " + arg0 + " " + arg1);
            try {
                String clientAddr = conn.toString().split("<->")[1];
                sendMsgToAll("Disconnected " + clientAddr);
            } catch (RuntimeException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onMessage(String msg) {
            sendMsgToAll(msg);
        }

        @Override
        public void onOpen(Connection conn) {
            members.add(this);
            this.conn = conn;
            System.out.println("onOpen " + conn);
            try {
                String clientAddr = conn.toString().split("<->")[1];
                sendMsgToAll("Connected " + clientAddr);
            } catch (RuntimeException e) {
                e.printStackTrace();
            }
        }

        public Connection getConn() {
            return conn;
        }

        void sendMsgToAll(String msg) {
            for (ChatWebSocket member : members) {
                try {
                    member.getConn().sendMessage(msg);
                } catch (IOException e) {
                    e.printStackTrace();
                    members.remove(member);
                }
            }
        }
    }
}
